/**
 * 地图工具类
 * 封装高德地图基本操作功能，如放大、缩小、旋转等
 */
export default class MapTools {
  /**
   * 构造函数
   * @param {Object} map - 高德地图实例
   * @param {Object} options - 配置选项
   */
  constructor(map, options = {}) {
    this.map = map;
    this.options = Object.assign(
      {
        // 默认配置
        rotationStep: 30, // 旋转步长（度）
        zoomStep: 1, // 缩放步长
        initialZoom: 11, // 初始缩放级别
        initialCenter: [116.397428, 39.90923], // 初始中心点
        initialRotation: 0, // 初始旋转角度
        initialPitch: 0, // 初始俯仰角度
        showPositionMarker: true, // 是否在定位时显示位置标记
        rotationDebounceTime: 0 // 旋转操作防抖时间（毫秒）
      },
      options
    );

    // 当前旋转角度
    this.rotation = this.options.initialRotation;
    // 确保初始旋转角度符合新的逻辑
    if (this.rotation < -360) {
      this.rotation = this.rotation % -360;
    } else if (this.rotation > 360) {
      this.rotation = this.rotation % 360;
    }
    
    // 旋转操作防抖标志
    this.isRotating = false;
    
    // 记录上次旋转方向，用于确保连续旋转的一致性
    this.lastRotationDirection = null;
    
    // 旋转防抖定时器
    this.rotationTimer = null;
    
    // 定位标记
    this.positionMarker = null;
    
    // 地理定位对象
    this.geolocation = null;
  }

  /**
   * 放大地图
   * @param {number} step - 放大步长，默认使用配置中的zoomStep
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  zoomIn(step = this.options.zoomStep) {
    if (this.map) {
      const currentZoom = this.map.getZoom();
      this.map.setZoom(currentZoom + step);
    }
    return this;
  }

  /**
   * 缩小地图
   * @param {number} step - 缩小步长，默认使用配置中的zoomStep
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  zoomOut(step = this.options.zoomStep) {
    if (this.map) {
      const currentZoom = this.map.getZoom();
      this.map.setZoom(currentZoom - step);
    }
    return this;
  }

  /**
   * 设置地图缩放级别
   * @param {number} zoom - 缩放级别
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  setZoom(zoom) {
    if (this.map) {
      this.map.setZoom(zoom);
    }
    return this;
  }

  /**
   * 获取当前缩放级别
   * @returns {number} 当前缩放级别
   */
  getZoom() {
    return this.map ? this.map.getZoom() : null;
  }

  /**
   * 处理连续旋转操作
   * 当用户在防抖期间继续点击旋转按钮时，记录操作并在防抖结束后执行
   * 现在不处理连续旋转，此方法保留但不执行任何操作
   * @private
   */
  _handleContinuousRotation() {
    // 不处理连续旋转
    // 重置方向记录
    this.lastRotationDirection = null;
  }

  /**
   * 顺时针旋转地图
   * @param {number} angle - 旋转角度，默认使用配置中的rotationStep
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  rotateClockwise(angle = this.options.rotationStep) {
    // 如果正在旋转中且有定时器，则取消之前的定时器并允许新的旋转
    if (this.isRotating && this.rotationTimer) {
      clearTimeout(this.rotationTimer);
      this.rotationTimer = null;
      this.isRotating = false;
    }
    
    if (this.map && !this.isRotating) {
      this.isRotating = true;
      
      // 记录当前旋转方向
      this.lastRotationDirection = 'clockwise';
      
      // 顺时针旋转，角度从0到360度
      this.rotation = (this.rotation + angle) % 360;
      this.map.setRotation(this.rotation);
      
      // 设置防抖，使用配置中的防抖时间
      this.rotationTimer = setTimeout(() => {
        this.isRotating = false;
        this.rotationTimer = null;
        
        // 不处理连续旋转
      }, this.options.rotationDebounceTime);
    } else if (this.map) {
      // 如果地图存在但正在旋转中，记录当前方向以便后续操作
      this.lastRotationDirection = 'clockwise';
    }
    return this;
  }

  /**
   * 逆时针旋转地图
   * @param {number} angle - 旋转角度，默认使用配置中的rotationStep
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  rotateCounterClockwise(angle = this.options.rotationStep) {
    // 如果正在旋转中且有定时器，则取消之前的定时器并允许新的旋转
    if (this.isRotating && this.rotationTimer) {
      clearTimeout(this.rotationTimer);
      this.rotationTimer = null;
      this.isRotating = false;
    }
    
    if (this.map && !this.isRotating) {
      this.isRotating = true;
      
      // 记录当前旋转方向
      this.lastRotationDirection = 'counter-clockwise';
      
      // 逆时针旋转，角度从0到-360度
      this.rotation = (this.rotation - angle);
      if (this.rotation < -360) {
        this.rotation = this.rotation % -360;
      }
      this.map.setRotation(this.rotation);
      
      // 设置防抖，使用配置中的防抖时间
      this.rotationTimer = setTimeout(() => {
        this.isRotating = false;
        this.rotationTimer = null;
        
        // 不处理连续旋转
      }, this.options.rotationDebounceTime);
    } else if (this.map) {
      // 如果地图存在但正在旋转中，记录当前方向以便后续操作
      this.lastRotationDirection = 'counter-clockwise';
    }
    return this;
  }

  /**
   * 设置地图旋转角度
   * @param {number} angle - 旋转角度（-360到360度）
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  setRotation(angle) {
    if (this.map) {
      // 处理角度范围
      if (angle >= 0) {
        this.rotation = angle % 360;
      } else {
        // 负角度处理
        this.rotation = angle;
        if (this.rotation < -360) {
          this.rotation = this.rotation % -360;
        }
      }
      this.map.setRotation(this.rotation);
    }
    return this;
  }

  /**
   * 获取当前旋转角度
   * @returns {number} 当前旋转角度（-360到360度）
   */
  getRotation() {
    return this.rotation;
  }

  /**
   * 设置地图俯仰角度
   * @param {number} pitch - 俯仰角度（0-83度）
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  setPitch(pitch) {
    if (this.map) {
      // 高德地图俯仰角度范围为0-83度
      const validPitch = Math.max(0, Math.min(83, pitch));
      this.map.setPitch(validPitch);
    }
    return this;
  }

  /**
   * 获取当前俯仰角度
   * @returns {number} 当前俯仰角度
   */
  getPitch() {
    return this.map ? this.map.getPitch() : null;
  }

  /**
   * 设置地图中心点
   * @param {Array} center - 中心点坐标 [lng, lat]
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  setCenter(center) {
    if (this.map) {
      this.map.setCenter(center);
    }
    return this;
  }

  /**
   * 获取当前中心点
   * @returns {Array} 当前中心点坐标 [lng, lat]
   */
  getCenter() {
    return this.map ? this.map.getCenter() : null;
  }

  /**
   * 设置地图缩放级别和中心点
   * @param {number} zoom - 缩放级别
   * @param {Array} center - 中心点坐标 [lng, lat]
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  setZoomAndCenter(zoom, center) {
    if (this.map) {
      this.map.setZoomAndCenter(zoom, center);
    }
    return this;
  }

  /**
   * 重置地图视图到初始状态
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  resetMapView() {
    if (this.map) {
      // 清除旋转定时器
      if (this.rotationTimer) {
        clearTimeout(this.rotationTimer);
        this.rotationTimer = null;
      }
      
      // 重置旋转状态
      this.isRotating = false;
      
      // 重置旋转角度为0
      this.rotation = 0;
      this.map.setRotation(this.rotation);

      // 重置旋转方向记录
      this.lastRotationDirection = null;

      // 重置俯仰角度为0
      this.map.setPitch(0);

      // 不再重置缩放级别和中心点
    }
    return this;
  }

  /**
   * 添加地图控件
   * @param {Object} control - 地图控件实例
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  addControl(control) {
    if (this.map) {
      this.map.addControl(control);
    }
    return this;
  }

  /**
   * 移除地图控件
   * @param {Object} control - 地图控件实例
   * @returns {MapTools} - 返回实例本身，支持链式调用
   */
  removeControl(control) {
    if (this.map) {
      this.map.removeControl(control);
    }
    return this;
  }

  /**
   * 定位当前位置
   * @returns {Promise} 返回Promise对象，定位成功后解析
   */
  locateCurrentPosition() {
    return new Promise((resolve, reject) => {
      if (!this.map) {
        reject(new Error('地图实例不存在'));
        return;
      }

      // 确保AMap.Geolocation插件已加载
      if (!window.AMap.Geolocation) {
        reject(new Error('AMap.Geolocation插件未加载'));
        return;
      }

      // 如果已经存在定位对象，则直接使用
      if (!this.geolocation) {
        this.geolocation = new window.AMap.Geolocation({
          enableHighAccuracy: true, // 是否使用高精度定位，默认:true
          timeout: 10000,           // 超过10秒后停止定位，默认：无穷大
          maximumAge: 0,            // 定位结果缓存0毫秒，默认：0
          convert: true,            // 自动偏移坐标，偏移后的坐标为高德坐标，默认：true
          showButton: false,        // 显示定位按钮，默认：true
          buttonPosition: 'LB',     // 定位按钮停靠位置，默认：'LB'，左下角
          buttonOffset: new window.AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
          showMarker: false,        // 定位成功后在定位到的位置显示点标记，默认：true
          showCircle: false,        // 定位成功后用圆圈表示定位精度范围，默认：true
          panToLocation: false,     // 定位成功后将定位到的位置作为地图中心点，默认：true
          zoomToAccuracy: false     // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
        });

        this.map.addControl(this.geolocation);
      }

      // 监听定位完成事件
      window.AMap.event.addListenerOnce(this.geolocation, 'complete', (status) => {
        // 获取定位信息
        const position = [status.position.lng, status.position.lat];
        
        // 设置地图中心点为当前位置
        this.map.setCenter(position);
        
        // 如果需要显示位置标记
        if (this.options.showPositionMarker) {
          // 如果已有标记，先移除
          if (this.positionMarker) {
            this.map.remove(this.positionMarker);
          }
          
          // 创建新标记
          this.positionMarker = new window.AMap.Marker({
            position: position,
            icon: new window.AMap.Icon({
              // 使用蓝色定位图标
              image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
              size: new window.AMap.Size(32, 32),
              imageSize: new window.AMap.Size(32, 32)
            }),
            offset: new window.AMap.Pixel(-16, -32),
            zIndex: 100,
            title: '当前位置'
          });
          
          // 添加到地图
          this.map.add(this.positionMarker);
          
          // 添加脉冲动画效果
          this.positionMarker.setAnimation('AMAP_ANIMATION_PULSE');
        }
        
        resolve({
          position: position,
          accuracy: status.accuracy,
          isConverted: status.isConverted,
          info: status.formattedAddress || ''
        });
      });

      // 监听定位错误事件
      window.AMap.event.addListenerOnce(this.geolocation, 'error', (error) => {
        reject(error);
      });

      // 开始定位
      this.geolocation.getCurrentPosition();
    });
  }

  /**
   * 销毁工具实例
   */
  destroy() {
    // 移除定位标记
    if (this.positionMarker && this.map) {
      this.map.remove(this.positionMarker);
      this.positionMarker = null;
    }
    
    // 移除定位控件
    if (this.geolocation && this.map) {
      this.map.removeControl(this.geolocation);
      this.geolocation = null;
    }
    
    this.map = null;
    this.options = null;
  }
}